{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model: AdaBoost"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Importing Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import _pickle as pickle\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score, confusion_matrix, classification_report\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading in Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_excel('../top10_features.xlsx')\n",
    "df = df.drop(df.columns[0], axis = 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scaling the Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "\n",
    "features_df = df.drop([\"Decision\"], 1)\n",
    "\n",
    "scaled_df = pd.DataFrame(scaler.fit_transform(features_df), \n",
    "                               index=features_df.index, \n",
    "                               columns=features_df.columns)\n",
    "\n",
    "df = scaled_df.join(df.Decision)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Splitting the Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df.drop([\"Decision\"], 1)\n",
    "y = df.Decision\n",
    "\n",
    "# Train, test, split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Function for plotting confusion matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_confusion_matrix(y_true, y_pred, labels=[\"Sell\", \"Buy\", \"Hold\"], \n",
    "                          normalize=False, title=None, cmap=plt.cm.coolwarm):\n",
    "\n",
    "    cm = confusion_matrix(y_true, y_pred)\n",
    "    fig, ax = plt.subplots(figsize=(12,6))\n",
    "    im = ax.imshow(cm, interpolation='nearest', cmap=cmap)\n",
    "    ax.figure.colorbar(im, ax=ax)\n",
    "    # We want to show all ticks...\n",
    "    ax.set(xticks=np.arange(cm.shape[1]),\n",
    "           yticks=np.arange(cm.shape[0]),\n",
    "           # ... and label them with the respective list entries\n",
    "           xticklabels=labels, yticklabels=labels,\n",
    "           title=title,\n",
    "           ylabel='ACTUAL',\n",
    "           xlabel='PREDICTED')\n",
    "    # Rotate the tick labels and set their alignment.\n",
    "    plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n",
    "             rotation_mode=\"anchor\")\n",
    "    # Loop over data dimensions and create text annotations.\n",
    "    fmt = '.2f' if normalize else 'd'\n",
    "    thresh = cm.max() / 1.5\n",
    "    for i in range(cm.shape[0]):\n",
    "        for j in range(cm.shape[1]):\n",
    "            ax.text(j, i, format(cm[i, j], fmt),\n",
    "                    ha=\"center\", va=\"center\",\n",
    "                    color=\"snow\" if cm[i, j] > thresh else \"orange\",\n",
    "                    size=26)\n",
    "    ax.grid(False)\n",
    "    fig.tight_layout()\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Modeling\n",
    "The preferred evaluation metric used will be __Precision__ for each class.  They will be optimized using the __F1 Score-Macro-Average__ to balance the Precision and Recall.  This is done because we want to not only be correct when predicting but also make a decent amount of predictions for each class.  Classes such as 'Buy' and 'Sell' are more important than 'Hold'."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fitting and Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AdaBoostClassifier(algorithm='SAMME.R', base_estimator=None, learning_rate=1.0,\n",
       "                   n_estimators=50, random_state=None)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Importing the model\n",
    "from sklearn.ensemble import AdaBoostClassifier\n",
    "\n",
    "# Fitting and training\n",
    "clf = AdaBoostClassifier()\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Printing out Evaluation Metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "        Sell       0.20      0.33      0.25         6\n",
      "         Buy       0.43      0.33      0.38         9\n",
      "        Hold       0.00      0.00      0.00         2\n",
      "\n",
      "    accuracy                           0.29        17\n",
      "   macro avg       0.21      0.22      0.21        17\n",
      "weighted avg       0.30      0.29      0.29        17\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    }
   ],
   "source": [
    "# Classifier predictions\n",
    "pred = clf.predict(X_test)\n",
    "\n",
    "#Printing out results\n",
    "report = classification_report(y_test, pred, target_names=['Sell', 'Buy', 'Hold'])\n",
    "print(report)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Confusion Matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_confusion_matrix(y_test, pred, title=\"Confusion Matrix\")\n",
    "np.set_printoptions(precision=1)\n",
    "# Plot non-normalized confusion matrix\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tuning Model Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parameters to Tune\n",
    "params = {'n_estimators': [50, 100, 200, 500],\n",
    "          'learning_rate': [1, .1, .01]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 3 folds for each of 12 candidates, totalling 36 fits\n",
      "[CV] learning_rate=1, n_estimators=50 ................................\n",
      "[CV]  learning_rate=1, n_estimators=50, score=(train=0.892, test=0.264), total=   0.2s"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "[CV] learning_rate=1, n_estimators=50 ................................\n",
      "[CV]  learning_rate=1, n_estimators=50, score=(train=0.892, test=0.380), total=   0.2s\n",
      "[CV] learning_rate=1, n_estimators=50 ................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.1s remaining:    0.0s\n",
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed:    0.3s remaining:    0.0s\n",
      "[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    0.5s remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=1, n_estimators=50, score=(train=0.876, test=0.307), total=   0.2s\n",
      "[CV] learning_rate=1, n_estimators=100 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=100, score=(train=0.874, test=0.179), total=   0.2s\n",
      "[CV] learning_rate=1, n_estimators=100 ...............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   4 out of   4 | elapsed:    0.7s remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=1, n_estimators=100, score=(train=0.964, test=0.389), total=   0.2s\n",
      "[CV] learning_rate=1, n_estimators=100 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=100, score=(train=0.857, test=0.307), total=   0.2s\n",
      "[CV] learning_rate=1, n_estimators=200 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=200, score=(train=0.892, test=0.284), total=   0.3s\n",
      "[CV] learning_rate=1, n_estimators=200 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=200, score=(train=0.964, test=0.449), total=   0.3s\n",
      "[CV] learning_rate=1, n_estimators=200 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=200, score=(train=0.878, test=0.291), total=   0.4s\n",
      "[CV] learning_rate=1, n_estimators=500 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=500, score=(train=0.891, test=0.318), total=   0.9s\n",
      "[CV] learning_rate=1, n_estimators=500 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=500, score=(train=0.964, test=0.488), total=   0.8s\n",
      "[CV] learning_rate=1, n_estimators=500 ...............................\n",
      "[CV]  learning_rate=1, n_estimators=500, score=(train=0.859, test=0.262), total=   0.9s\n",
      "[CV] learning_rate=0.1, n_estimators=50 ..............................\n",
      "[CV]  learning_rate=0.1, n_estimators=50, score=(train=0.837, test=0.217), total=   0.1s\n",
      "[CV] learning_rate=0.1, n_estimators=50 ..............................\n",
      "[CV]  learning_rate=0.1, n_estimators=50, score=(train=0.798, test=0.253), total=   0.1s\n",
      "[CV] learning_rate=0.1, n_estimators=50 ..............................\n",
      "[CV]  learning_rate=0.1, n_estimators=50, score=(train=0.804, test=0.568), total=   0.1s\n",
      "[CV] learning_rate=0.1, n_estimators=100 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=100, score=(train=0.836, test=0.217), total=   0.5s\n",
      "[CV] learning_rate=0.1, n_estimators=100 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=100, score=(train=0.946, test=0.368), total=   0.2s\n",
      "[CV] learning_rate=0.1, n_estimators=100 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=100, score=(train=0.743, test=0.431), total=   0.2s\n",
      "[CV] learning_rate=0.1, n_estimators=200 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=200, score=(train=0.892, test=0.217), total=   0.4s\n",
      "[CV] learning_rate=0.1, n_estimators=200 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=200, score=(train=0.946, test=0.391), total=   0.4s\n",
      "[CV] learning_rate=0.1, n_estimators=200 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=200, score=(train=0.823, test=0.431), total=   0.4s\n",
      "[CV] learning_rate=0.1, n_estimators=500 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=500, score=(train=0.892, test=0.234), total=   1.3s\n",
      "[CV] learning_rate=0.1, n_estimators=500 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=500, score=(train=0.910, test=0.346), total=   0.8s\n",
      "[CV] learning_rate=0.1, n_estimators=500 .............................\n",
      "[CV]  learning_rate=0.1, n_estimators=500, score=(train=0.845, test=0.310), total=   0.9s\n",
      "[CV] learning_rate=0.01, n_estimators=50 .............................\n",
      "[CV]  learning_rate=0.01, n_estimators=50, score=(train=0.467, test=0.212), total=   0.1s\n",
      "[CV] learning_rate=0.01, n_estimators=50 .............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=0.01, n_estimators=50, score=(train=0.492, test=0.242), total=   0.1s\n",
      "[CV] learning_rate=0.01, n_estimators=50 .............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=0.01, n_estimators=50, score=(train=0.408, test=0.372), total=   0.2s\n",
      "[CV] learning_rate=0.01, n_estimators=100 ............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=0.01, n_estimators=100, score=(train=0.467, test=0.212), total=   0.2s\n",
      "[CV] learning_rate=0.01, n_estimators=100 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=100, score=(train=0.525, test=0.318), total=   0.1s\n",
      "[CV] learning_rate=0.01, n_estimators=100 ............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=0.01, n_estimators=100, score=(train=0.603, test=0.372), total=   0.2s\n",
      "[CV] learning_rate=0.01, n_estimators=200 ............................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  learning_rate=0.01, n_estimators=200, score=(train=0.757, test=0.212), total=   0.3s\n",
      "[CV] learning_rate=0.01, n_estimators=200 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=200, score=(train=0.651, test=0.253), total=   0.4s\n",
      "[CV] learning_rate=0.01, n_estimators=200 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=200, score=(train=0.721, test=0.372), total=   0.4s\n",
      "[CV] learning_rate=0.01, n_estimators=500 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=500, score=(train=0.800, test=0.217), total=   0.8s\n",
      "[CV] learning_rate=0.01, n_estimators=500 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=500, score=(train=0.797, test=0.191), total=   0.7s\n",
      "[CV] learning_rate=0.01, n_estimators=500 ............................\n",
      "[CV]  learning_rate=0.01, n_estimators=500, score=(train=0.765, test=0.513), total=   1.0s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done  36 out of  36 | elapsed:   15.9s finished\n",
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\model_selection\\_search.py:813: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.\n",
      "  DeprecationWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=3, error_score='raise-deprecating',\n",
       "             estimator=AdaBoostClassifier(algorithm='SAMME.R',\n",
       "                                          base_estimator=None,\n",
       "                                          learning_rate=1.0, n_estimators=50,\n",
       "                                          random_state=None),\n",
       "             iid='warn', n_jobs=None,\n",
       "             param_grid={'learning_rate': [1, 0.1, 0.01],\n",
       "                         'n_estimators': [50, 100, 200, 500]},\n",
       "             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "             scoring='f1_macro', verbose=5)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search = GridSearchCV(clf, params, cv=3, return_train_score=True, verbose=5, scoring='f1_macro')\n",
    "\n",
    "search.fit(X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tuned Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean Training Score: 0.7923833174478029\n",
      "Mean Testing Score: 0.9164268201684256\n",
      "\n",
      "Best Parameter Found:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'learning_rate': 1, 'n_estimators': 500}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(\"Mean Training Score:\", np.mean(search.cv_results_['mean_train_score']))\n",
    "print(\"Mean Testing Score:\", search.score(X, y))\n",
    "print(\"\\nBest Parameter Found:\")\n",
    "search.best_params_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model with the Best Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AdaBoostClassifier(algorithm='SAMME.R', base_estimator=None, learning_rate=1,\n",
       "                   n_estimators=500, random_state=None)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search_clf = search.best_estimator_\n",
    "\n",
    "search_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Results from Optimum Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "        Sell       0.27      0.50      0.35         6\n",
      "         Buy       0.50      0.33      0.40         9\n",
      "        Hold       0.00      0.00      0.00         2\n",
      "\n",
      "    accuracy                           0.35        17\n",
      "   macro avg       0.26      0.28      0.25        17\n",
      "weighted avg       0.36      0.35      0.34        17\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\72445\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
      "  'precision', 'predicted', average, warn_for)\n"
     ]
    }
   ],
   "source": [
    "# Classifier predictions\n",
    "s_pred = search_clf.predict(X_test)\n",
    "\n",
    "#Printing out results\n",
    "report = classification_report(y_test, s_pred, target_names=['Sell', 'Buy', 'Hold'])\n",
    "print(report)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Confusion Matrix for Optimum Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_confusion_matrix(y_test, s_pred, title=\"Confusion Matrix\")\n",
    "np.set_printoptions(precision=1)\n",
    "# Plot non-normalized confusion matrix\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
